<template>
  <div class="upload-container">
    <el-upload
      :file-list="file"
      :on-remove="handleRemove"
      :http-request="set_upload_param"
      :before-upload="beforeUpload"
      class="editor-slide-upload"
      :limit="limit"
      :multiple="multiple"
      :on-preview="handlePictureCardPreview"
      :on-success="handleSuccess"
      action="111"
      :on-exceed="handleExceed"
      :accept="accept"
      :list-type="listType"
      :on-progress="handleProgress"
    >
      <i v-if="listType === 'picture-card'" class="el-icon-plus" />
      <el-button v-if="listType === 'text'" size="small" type="primary">点击上传</el-button>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible" append-to-body>
      <img width="100%" :src="dialogImageUrl" alt>
    </el-dialog>
  </div>
</template>

<script>
import { getFileToken } from '@/api/general/file'
import axios from 'axios'
import md5 from 'md5'

export default {
  model: {
    prop: 'file',
    event: 'save'
  },
  props: {
    listType: {
      type: String,
      default: () => 'picture-card'
    },
    file: {
      type: Array,
      default: () => []
    },
    color: {
      type: String,
      default: '#1890ff'
    },
    limit: {
      type: Number,
      default: 1
    },
    multiple: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      dialogVisible: false,
      dialogImageUrl: '',
      listObj: {},
      fileList: [],
      UploadObj: [],
      customColor: '',
      percentage: 0,
      plUploader: null,
      token: {}
    }
  },
  computed: {
    accept: function() {
      let accept = ''
      if (this.listType === 'picture-card') {
        accept = '.jpg, .jpeg, .png, .gif, .bmp, .pdf, .JPG, .JPEG, .PBG, .GIF, .BMP, .PDF'
      }
      return accept
    }
  },
  mounted() {
    this.gettoken()
  },
  methods: {
    handleProgress(event, file, fileList) {
    },
    handleExceed(files, fileList) {
      this.$message({
        message: '上传文件数量超出限制',
        type: 'warning'
      })
    },
    handlePictureCardPreview(file) {
      if (this.listType === 'text') {
        return
      }
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    random_string(len) {
      len = len || 32
      const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
      const maxPos = chars.length
      let pwd = ''
      for (let i = 0; i < len; i++) {
        pwd += chars.charAt(Math.floor(Math.random() * maxPos))
      }
      return pwd
    },
    gettoken() {
      const dir = 'elec/'
      return new Promise((resolve, reject) => {
        getFileToken({ dir }).then(result => {
          this.token = result.data
          resolve(result.data)
        })
      })
    },
    checkAllSuccess() {
      return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess)
    },
    handleSubmit() {
      const arr = Object.keys(this.listObj).map(v => this.listObj[v])
      if (!this.checkAllSuccess()) {
        this.$message('Please wait for all images to be uploaded successfully. If there is a network problem, please refresh the page and upload again!')
        return
      }
      this.$emit('successCBK', arr)
      this.listObj = {}
      this.fileList = []
      this.dialogVisible = false
    },
    handleSuccess(response, file) {
      const uid = file.uid
      const objKeyArr = Object.keys(this.listObj)
      for (let i = 0, len = objKeyArr.length; i < len; i++) {
        if (this.listObj[objKeyArr[i]].uid === uid) {
          this.listObj[objKeyArr[i]].url = response.data.fileUrl
          this.listObj[objKeyArr[i]].fileId = response.data.fileId
          this.listObj[objKeyArr[i]].hasSuccess = true
          this.$emit('save', [
            ...this.file,
            {
              fileId: response.data.fileId,
              fileDesc: response.data.fileDesc ? response.data.fileDesc : '',
              fileSort: '',
              url: response.data.fileUrl,
              name: file.name
            }
          ])
          return
        }
      }
    },
    handleRemove(file) {
      const uid = file.uid
      const objKeyArr = Object.keys(this.listObj)
      const list = this.file.filter(item => item.fileId !== file.fileId)
      this.$emit('save', list)
      for (let i = 0, len = objKeyArr.length; i < len; i++) {
        if (this.listObj[objKeyArr[i]].uid === uid) {
          delete this.listObj[objKeyArr[i]]
          return
        }
      }
    },
    set_upload_param(param) {
      const { file } = param
      const date = new Date()
      const year = date.getFullYear()
      const month = date.getMonth() + 1
      const day = date.getDate()
      const filename = md5(file.name + new Date().getTime())
      const nameList = file.name.split('.')
      const name = `${this.token.dir}/${year}-${month}-${day}/${filename}.${nameList[nameList.length - 1]}`
      const formData = new FormData()
      formData.append('x:filename', file.name)
      formData.append('name', file.name)
      formData.append('key', name)
      formData.append('policy', this.token.policy)
      formData.append('OSSAccessKeyId', this.token.accessid)
      formData.append('success_action_status', 200)
      formData.append('callback', this.token.callback)
      formData.append('signature', this.token.signature)
      formData.append('file', file)
      axios.post(this.token.host, formData,
        {
          onUploadProgress: p => {
            param.file.percent = 100 * (p.loaded / p.total)
            param.onProgress(param.file)
          }
        })
        .then(response => {
          param.onSuccess(response)
        })
        .catch((error) => {
          console.log(error)
        })
    },
    beforeUpload(file) {
      const _self = this
      return new Promise((resolve, reject) => {
        const fileName = file.uid
        this.listObj[fileName] = {}
        if (_self.listType === 'picture-card') {
          const _URL = window.URL || window.webkitURL
          const img = new Image()
          img.src = _URL.createObjectURL(file)
          img.onload = function() {
            _self.listObj[fileName] = { hasSuccess: false, uid: file.uid, width: this.width, height: this.height }
          }
        } else {
          _self.listObj[fileName] = { hasSuccess: false, uid: file.uid, width: this.width, height: this.height }
        }
        resolve(true)
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.editor-slide-upload {
  margin-bottom: 20px;
}
</style>
